<?php

$mcrp = './';
include_once('functions/session.php');

$head = '<link href="nano/nano.css" rel="stylesheet" media="screen" type="text/css" title="style" />
<script type="text/javascript" src="nano/nanomenu.js"></script>';
include($mcrp . 'skin/default.php');
include($mcrp . 'skin/header.php');

?>
<div class="mc_box">
	<h3><a href="nano.php">Nanocontest</a> :: Documentation</h3>
	<?php if($mcuser->id == 0) { ?>
	<div><center><img src="img/stop-trackback.png"><br/>Vous devez être connecté pour accéder à cette page.<br />Si vous n'êtes pas encore inscrit, rendez-vous sur la page d'<a href="register.php">inscription</a>.</center></div>
	<?php } else { ?>
	<div class="mc_box_content"><br />
	<div class="nc_button_left" onclick="NanoDisplayDoc('nc_doc_pres');">Présentation</div><div class="nc_button_middle" onclick="NanoDisplayDoc('nc_doc_prog');">Programmation</div><div class="nc_button_right" onclick="NanoDisplayDoc('nc_doc_ref');">Référence</div><br /><br />
	<div id="nc_doc_pres">
		<h3>Présentation</h3>
		<div class="mc_box_content">Les Nanocontests sont un jeu de programmation opposant plusieurs programmes exécutés dans une machine virtuelle. L'objectif de chaque joueur est de faire terminer les programmes adverses. Le vainqueur est le dernier encore en cours d'exécution. la programmation s'effectue dans un langage assembleur spécialement créé pour les Nanocontests.<br />
		<h4><i>Comment cela fonctionne-t-il ?</i></h4>
		Les programmes sont placés dans une mémoire virtuelle. Celle-ci est représentée symboliquement sur la page de la <a href="nanovm.php">machine virtuelle</a> comme une grille. La mémoire comporte 32768 cases (256*128). Chacune d'elles contient un nombre qui peut représenter ou non une instruction, une partie de code exécutable. Chaque programme est copié aléatoirement dans une zone de la mémoire au début des combats. Puis, ils exécutent alternativement une instruction à la fois, contenue dans la case mémoire courante. Ils passent ensuite à la case suivante. Si le nombre contenu dans celle-ci ne représente pas une instruction, le programme crash et est donc terminé. Le joueur est éliminé.<br />
		<h4><i>Comment participer ?</i></h4>
		Pour participer aux combats, vous devez créer un programme. Cela se passe sur la page <a href="nanoeditor.php">Compilateur</a>. Vous pouvez enregistrer chacun des programmes que vous réalisez. La <a href="nanovm.php">machine virtuelle</a> vous permet de les tester, avant de participer aux combats.<br />
		Ceux-ci s'organisent en trois temps :
		<ul>
			<li><b>L'inscription :</b> vous pouvez vous inscrire aux combats auxquels il reste des places de libres, ou en créer un vous-même. Une autre option vous permet de défier un ou plusieurs joueurs en particulier.</li>
			<li><b>L'envoi des programmes :</b> une fois que toutes les places sont remplies, vous devez soumettre votre programme grâce au bouton <i>Gérer</i> à droite de votre pseudo. Il doit être enregistré au préalable et doit pouvoir être compilé correctement.</li>
			<li><b>Le combat en lui-même :</b> lorsque tous les joueurs ont envoyé leur programme, un bouton <i>Visionner</i> apparait à droite de la liste des joueurs, vous permettant d'exécuter le combat. La première exécution s'effectue simultanément sur le serveur afin de déterminer le vainqueur.</li>
		</ul><br />
		</div>
	</div>
	<div id="nc_doc_prog" style="display:none;">
		<h3>Programmation</h3>
		<div class="mc_box_content">
			La programmation s'effectue dans un langage assembleur proche, au niveau des instructions, de l'assembleur x86. Nous allons détailler les différents aspects.<br />
			<h4><i>Les registres</i></h4>
			La machine virtuelle dispose de zones mémoires au sein du "processeur" appelées registres. Il y en a 8 : <code>ax, bx, cx, dx, fx, ip, sp et bp</code>. Ils contiennent chacun un entier (codé sur 4 octets donc compris en 0 et un peu plus de 4 milliards). Ces registres peuvent être manipulés à loisir par le programme. Pour cela, il existes différentes instructions : <br />
			par exemple, si l'on veut mettre '1' dans le registre <code>ax</code>, on utilise l'instruction <code>mov</code> comme ceci :<br />
			<div class="nano">mov ax, 1</div>
			De même, on peut mettre le contenu du registre <code>cx</code>, dans le registre <code>dx</code> : 
			<div class="nano">mov dx, cx</div>Vous pouvez donc modifier le contenu d'un registre en y plaçant directement une valeur, ou en ajoutant, retranchant, multipliant une valeur ou un autre registre. La liste de toutes les instructions est détaillé dans la partie <a href="#" onclick="NanoDisplayDoc('nc_doc_ref');return false;">Référence</a>.<br />
			Les registres <code>ax, bx, cx, dx</code> sont entièrement dédiés au programme et peuvent être modifiés sans conséquences. Le registre <code>ip</code> contient l'adresse de l'instruction en cours d'exécution. Il n'est pas recommendé de modifier cette valeur, sous peine de crash. Vous pouvez cependant récupérer sa valeur sans danger. Les registres <code>bp</code> et <code>sp</code> contiennent respectivement l'adresse de base de la pile et l'adresse du haut de la pile. Un paragraphe lui est dédié un peu plus loin. Enfin, le registre <code>fx</code> contient l'état des flags. De même nous y reviendrons un peu plus loin.<br /><br />
			<h4><i>La mémoire</i></h4>
			La mémoire est constituée de 32768 cases, chacune de 4 octets. Elles sont repérées par une adresse absolue. L'adresse 0 correspond à la première case, ... L'adresse 32767 correspond à la dernière. L'adressage est cependant cyclique, c'est-à-dire que l'adresse 32768 existe est correspond à la case 0.<br />Dans les programme vous disposez de deux types d'adresses : les adresses absolues, fonctionnant comme expliqué précédemment, et les adresses relatives. Celles-ci permettent de repérer une case par rapport à l'instruction courante. Prenons un exemple :
			<div class="nano">mov ax, 123 ; on place dans ax l'adresse 123<br />mov ax, +1 ; on place dans ax l'adresse de la case suivante</div>
			Pour accéder au contenu d'une case mémoire, on utilise des parenthèses :
			<div class="nano">mov ax, (123) ; place place le contenu de la case 123 dans ax<br />mov ax, (+1) ; on place le contenu de la case suivante dans ax<br /><br />mov ax, -1<br />mov bx, (ax) ; on place le contenu de la case  dont l'adresse est la valeur de ax (ici deux cases avant) dans bx</div><br />
			<h4><i>Les sauts et conditions</i></h4>
			<h4><i>La pile</i></h4>
			<h4><i>Exemple complet</i></h4>
		</div>
	</div>
	<div id="nc_doc_ref" style="display:none;">
		<h3>Référence</h3>
		<ul><li><a href="#nc_doc_tech">Caractéristiques techniques</a></li>
		<li><a href="#nc_doc_inst">Instructions</a></li>
		<li><a href="#nc_doc_reg">Registres</a></li>
		<li><a href="#nc_doc_flag">Flags</a></li>
		<li><a href="#nc_doc_func">Fonctions</a></li>
		<li><a href="#nc_doc_addr">Syntaxe</a></li>
		<li><a href="#nc_doc_example">Exemples</a></li></ul><br />
		<table id="nc_doc_tech" class="mc_table">
			<tr>
				<th colspan=2>Caractéristiques techniques</th>
			</tr>
			<tr>
				<td style="width:180px">Taille mémoire</td>
				<td>32768 (256*128) cases</td>
			</tr>
			<tr>
				<td>Taille d'une case</td>
				<td>4 octets</td>
			</tr>
		</table>
		<table id="nc_doc_inst" class="mc_table">
			<tr>
				<th style="width:180px">Instruction</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><code>mov regd, regs</code></td>
				<td>Copie le contenu du registre <code>regs</code> dans le registre regd</td>
			</tr>
			<tr>
				<td><code>mov regd, imm</code></td>
				<td>Copie la valeur <code>imm</code> dans le registre <code>regd</code></td>
			</tr>
			<tr>
				<td><code>mov regd, (regs)</code></td>
				<td>Copie le contenu de la case mémoire à l'adresse contenue dans le registre <code>regs</code> dans le registre regd</td>
			</tr>
			<tr>
				<td><code>mov regd, (imm)</code></td>
				<td>Copie le contenu de la case mémoire à l'adresse <code>imm</code> dans le registre <code>regd</code></td>
			</tr>
			<tr>
				<td><code>mov regd, (label)</code></td>
				<td>Copie le contenu de la case mémoire à l'adresse pointée par <code>label</code> dans le registre <code>regd</code></td>
			</tr>
			<tr>
				<td><code>mov (regd), regs</code></td>
				<td>Copie le contenu du registre <code>regs</code> dans la case mémoire à l'adresse contenue dans le registre <code>regs</code></td>
			</tr>
			<tr>
				<td><code>mov (imm), regs</code></td>
				<td>Copie le contenu du registre <code>regs</code> dans la case mémoire à l'adresse <code>imm</code></td>
			</tr>
			<tr>
				<td><code>add regd, regs</code><br /><code>sub regd, regs</code><br /><code>mul regd, regs</code></td>
				<td>Ajoute<br />Soustrait le contenu du registre <code>regs</code> au contenu du registre <code>regd</code><br />Multiplie</td>
			</tr>
			<tr>
				<td><code>add regd, (regs)</code><br /><code>sub regd, (regs)</code><br /><code>mul regd, (regs)</code></td>
				<td>Ajoute<br />Soustrait le contenu de la case mémoire à l'adresse contenue dans <code>regs</code> au contenu du registre <code>regd</code><br />Multiplie</td>
			</tr>
			<tr>
				<td><code>add regd, imm</code><br /><code>sub regd, imm</code><br /><code>mul regd, imm</code></td>
				<td>Ajoute<br />Soustrait la valeur <code>imm</code> au contenu du registre <code>regd</code><br />Multiplie</td>
			</tr>
			<tr>
				<td><code>add regd, (imm)</code><br /><code>sub regd, (imm)</code><br /><code>mul regd, (imm)</code></td>
				<td>Ajoute<br />Soustrait le contenu de la case mémoire à l'adresse <code>imm</code> au contenu du registre <code>regd</code><br />Multiplie</td>
			</tr>
			<tr>
				<td><code>inc regd</code></td>
				<td>Incrémente le contenu du registre <code>regd</code> d'une unité</td>
			</tr>
			<tr>
				<td><code>inc (regd)</code></td>
				<td>Incrémente d'une unité le contenu de la case mémoire à l'adresse contenue dans le registre <code>regd</code></td>
			</tr>
			<tr>
				<td><code>dec regd</code></td>
				<td>Décrémente le contenu du registre <code>regd</code> d'une unité</td>
			</tr>
			<tr>
				<td><code>dec (regd)</code></td>
				<td>Décrémente d'une unité le contenu de la case mémoire à l'adresse contenue dans le registre <code>regd</code></td>
			</tr>
			<tr>
				<td><code>and regd, regs</code><br /><code>or regd, regs</code><br /><code>xor regd, regs</code></td>
				<td>Effectue l'opération binaire <code>et/ou/ou exclusif</code> sur les registres <code>regd</code> et <code>regs</code>. Le résultat est placé dans <code>regd</code></td>
			</tr>
			<tr>
				<td><code>and regd, (regs)</code><br /><code>or regd, (regs)</code><br /><code>xor regd, (regs)</code></td>
				<td>Effectue l'opération binaire <code>et/ou/ou exclusif</code> sur le registre <code>regd</code> et le contenu de la case mémoire à l'adresse contenue dans <code>regs</code>. Le résultat est placé dans <code>regd</code></td>
			</tr>
			<tr>
				<td><code>and regd, imm</code><br /><code>or regd, imm</code><br /><code>xor regd, imm</code></td>
				<td>Effectue l'opération binaire <code>et/ou/ou exclusif</code> sur le registre <code>regd</code> et la valeur <code>imm</code>. Le résultat est placé dans <code>regd</code></td>
			</tr>
			<tr>
				<td><code>and regd, (imm)</code><br /><code>or regd, (imm)</code><br /><code>xor regd, (imm)</code></td>
				<td>Effectue l'opération binaire <code>et/ou/ou exclusif</code> sur le registre <code>regd</code> et le contenu de la case mémoire à l'adresse <code>imm</code>. Le résultat est placé dans <code>regd</code></td>
			</tr>
			<tr>
				<td><code>push reg</code></td>
				<td>Place le contenu du registre <code>reg</code> au dessus de la pile. <b>Attention</b> : les registres bp et sp sont initialisés à 0, donc la pile se situe à l'adresse 0. A vous de changer ces registres si vous voulez positionner la pile ailleurs.</td>
			</tr>
			<tr>
				<td><code>pop reg</code></td>
				<td>Place le sommet de la pile dans le registre <code>reg</code> et le dépile</td>
			</tr>
			<tr>
				<td><code>call reg</code></td>
				<td>Empile l'adresse de la case suivante puis saute à l'adresse contenue dans le registre <code>reg</code></td>
			</tr>
			<tr>
				<td><code>call addr</code></td>
				<td>Empile l'adresse de la case suivante puis saute à l'adresse <code>addr</code></td>
			</tr>
			<tr>
				<td><code>call flag, reg</code></td>
				<td>Empile l'adresse de la case suivante puis saute à l'adresse contenue dans le registre <code>reg</code> si la condition <code>flag</code> est vérifiée</td>
			</tr>
			<tr>
				<td><code>call flag, addr</code></td>
				<td>Empile l'adresse de la case suivante puis saute à l'adresse <code>addr</code> si la condition <code>flag</code> est vérifiée</td>
			</tr>
			<tr>
				<td><code>call fonction</code></td>
				<td>Appel une fonction prédéfinie : <a href="#nc_doc_func">tableau des fonctions disponibles</a></td>
			</tr>
			<tr>
				<td><code>ret</code></td>
				<td>Saute à l'adresse contenue au sommet de la pile, après l'avoir dépilée</td>
			</tr>
			<tr>
				<td><code>jmp imm</code></td>
				<td>Saut inconditionnel à l'adresse <code>imm</code></td>
			</tr>
			<tr>
				<td><code>jmp label</code></td>
				<td>Saut inconditionnel au label <code>label</code></td>
			</tr>
			<tr>
				<td><code>jmp flag, imm</code></td>
				<td>Saut conditionnel à l'adresse <code>imm</code></td>
			</tr>
			<tr>
				<td><code>jmp flag, label</code></td>
				<td>Saut conditionnel au label <code>label</code></td>
			</tr>
			<tr>
				<td><code>jmp reg</code></td>
				<td>Saut inconditionnel à l'adresse contenu dans le registre <code>reg</code></td>
			</tr>
			<tr>
				<td><code>jmp flag, reg</code></td>
				<td>Saut conditionnel à l'adresse contenu dans le registre <code>reg</code></td>
			</tr>
			<tr>
				<td><code>cmp regd, regs</code></td>
				<td>Compare les registres <code>regd</code> et <code>regs</code> et affecte les flags : <code>fz</code> si <code>regd</code> = <code>regs</code> ; <code>fnz</code> si <code>regd</code> &ne; <code>regs</code> ; <code>fp</code> si <code>regd</code> &ge; <code>regs</code> ; <code>fn</code> si <code>regd</code> &lt; <code>regs</code></td>
			</tr>
			<tr>
				<td><code>cmp regd, imm</code></td>
				<td>Compare le registre <code>regd</code> à la valeur <code>imm</code> et affecte les flags : <code>fz</code> si <code>regd</code> = <code>imm</code> ; <code>fnz</code> si <code>regd</code> &ne; <code>imm</code> ; <code>fp</code> si <code>regd</code> &ge; <code>imm</code> ; <code>fn</code> si <code>regd</code> &lt; <code>imm</code></td>
			</tr>
			<tr>
				<td><code>test reg</code></td>
				<td>Test le registre <code>reg</code> et affecte les flags : <code>fz</code> si <code>regd</code> = <code>0</code> ; <code>fnz</code> si <code>regd</code> &ne; <code>0</code> ; <code>fp</code> si <code>regd</code> &ge; <code>0</code> ; <code>fn</code> si <code>regd</code> &lt; <code>0</code></td>
			</tr>
			<tr>
				<td><code>djnz imm</code></td>
				<td>Décrémente <code>cx</code> et saute à l'adresse <code>imm</code> si <code>cx &ne; 0</code></td>
			</tr>
			<tr>
				<td><code>djnz label</code></td>
				<td>Décrémente <code>cx</code> et saute au label <code>label</code> si <code>cx &ne; 0</code></td>
			</tr>
			<tr>
				<td><code>shr reg</code></td>
				<td>Effectue un décalage d'un bit vers la droite sur le registre <code>reg</code>. Le flag <code>fc</code> est affecté si le bit le plus à droite est 1, <code>fnc</code> sinon.</td>
			</tr>
			<tr>
				<td><code>shl reg</code></td>
				<td>Effectue un décalage d'un bit vers la gauche sur le registre <code>reg</code>. Le flag <code>fc</code> est affecté si le bit le plus à gauche est 1, <code>fnc</code> sinon.</td>
			</tr>
		</table>
		<table id="nc_doc_reg" class="mc_table">
			<tr>
				<th style="width:180px">Registre</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><code>ax</code></td>
				<td></td>
			</tr>
			<tr>
				<td><code>bx</code></td>
				<td></td>
			</tr>
			<tr>
				<td><code>cx</code></td>
				<td></td>
			</tr>
			<tr>
				<td><code>dx</code></td>
				<td></td>
			</tr>
			<tr>
				<td><code>ip</code></td>
				<td>Adresse de l'instruction exécutée</td>
			</tr>
			<tr>
				<td><code>sp</code></td>
				<td>Adresse du sommet de la pile</td>
			</tr>
			<tr>
				<td><code>bp</code></td>
				<td>Adresse de la base de la pile</td>
			</tr>
		</table>
		<table id="nc_doc_flag" class="mc_table">
			<tr>
				<th style="width:180px">Flag</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><code>fz</code></td>
				<td>Résultat nul</td>
			</tr>
			<tr>
				<td><code>fnz</code></td>
				<td>Résultat non nul</td>
			</tr>
			<tr>
				<td><code>fc</code></td>
				<td>Retenue/débordement</td>
			</tr>
			<tr>
				<td><code>fnc</code></td>
				<td></td>
			</tr>
			<tr>
				<td><code>fp</code></td>
				<td>Résultat positif</td>
			</tr>
			<tr>
				<td><code>fn</code></td>
				<td>Résultat négatif</td>
			</tr>
		</table>
		<table id="nc_doc_func" class="mc_table">
			<tr>
				<th style="width:180px;">Fonction</th>
				<th style="width:200px;">Paramètres</th>
				<th>Description</th>
			</tr>
			<tr>
				<td>CreateThread</td>
				<td>Entrée :<br /><code>ax = addr</code></td>
				<td>Crée un thread qui débute à l'adresse <code>addr</code></td>
			</tr>
		</table>
		<table id="nc_doc_addr" class="mc_table">
			<tr>
				<th style="width:180px">Syntaxe</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><code>addr (ex : 1234)</code></td>
				<td>Adresse absolue. 1234 correspond à l'adresse de la 1234e case. Pour les adresses négatives, utilisez le symbole '~' (tilde) au lieu du symbole '-' (moins).</td>
			</tr>
			<tr>
				<td><code>±addr (ex : +1)</code></td>
				<td>Adresse relative par rapport à l'instruction courante. +1 est l'adresse de la case suivante.</td>
			</tr>
			<tr>
				<td><code>label:</code></td>
				<td>Un label peux remplacer une adresse dans un code assembleur. Il est remplacé par une adresse relative à la compilation.</td>
			</tr>
			<tr>
				<td><code>; commentaire<br />ret ; commentaire</code></td>
				<td>Syntaxe des commentaires dans les sources : sur une ligne et après une instruction.</td>
			</tr>
		</table>
		<br />
		<div id="nc_doc_example">
			<h3>Exemples</h3>
			<div class="mc_box_content">Voici un exemple de code : ce programme est un "bombardier", il écrit la valeur '1' (contenue dans dx) dans les cases mémoires de manière régulière (toutes les 5 cases).
			<div class="nano">mov ax, 50<br />add ax, ip<br />mov dx, 1<br />loop:<br />mov (ax), dx<br />add ax, 5<br />jmp loop</div>
			</div>
		</div>
	</div>
	</div>
	<?php } ?>
</div>

<?php
include($mcrp . 'skin/footer.php');
?>